Introdução

Análise exploratória de dados do RottenTomatoes sobre o ator Jake Gyllenhaal. O código empregado na extração dos dados aqui analizados e a descrição de como o usar encontra-se no repositório origem deste relatório.

  • Entradas que não contêm dados sobre bilheteria foram ignorados.




Data Overview

import_data("jake_gyllenhaal") 
filmes <- read_imported_data()
filmes %>% 
    glimpse()
Observations: 20
Variables: 5
$ avaliacao  <int> 92, 68, 73, 52, 73, 59, 82, 85, 92, 49, 35, 64, 47, 90, 87, 61, 62, 44, ...
$ filme      <chr> "Stronger", "Life", "Nocturnal Animals", "Demolition", "Everest", "South...
$ papel      <chr> "Jeff Bauman", "David Jordan", "Tony HastingsEdward Sheffield", "Davis M...
$ bilheteria <dbl> 4.2, 30.2, 10.7, 1.7, 46.6, 42.4, 61.0, 39.1, 54.7, 33.3, 90.8, 28.6, 9....
$ ano        <int> 2017, 2017, 2016, 2016, 2015, 2015, 2013, 2012, 2011, 2010, 2010, 2009, ...

Bilheteria

  • Dados de bilheteria se referem ao arrecadamento dentro dos Estados Unidos.
p <- filmes %>%
    ggplot(aes(x = ano, 
               y = bilheteria,
               text = paste("Filme:",filme,
                            "\nBilheteria:",
                            bilheteria,"m",
                            "\nAno:",ano))) + 
    geom_point(size = 4, color = paleta[1]) +
    labs(y = "Bilheteria", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
  • Entre os filmes em que Jake atuou um foge aos outros em termos de faturamento, o filme “The Day After Tomorrow” lançado em 2004.

  • É possível perceber uma tendência de queda no faturamento dos filmes em que Jake atuou após 2013.

filmes %>% 
    ggplot(aes(x = bilheteria)) + 
    geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0, 
                   fill = "grey", color = "black") + 
    geom_rug(size = .5) +
    scale_x_continuous(breaks=seq(0,200,20)) +
    labs(y = "Frequência Relativa", x = "Bilheteria")

  • Vemos claramente a disparidade entre “The Day After Tomorrow” e os outros filmes.

  • Nenhum valor fora do domínio de valores esperado, e.g. valores negativos.

p <- filmes %>% 
    ggplot(aes(x = "",
               y = bilheteria,
               label = filme,
               text = paste("Filme:",filme,
                            "\nBilheteria:",
                            bilheteria,"m"))) + 
    geom_jitter(width = .05, alpha = .3, size = 3) + 
    labs(x = "", y="Bilheteria")
ggplotly(p, tooltip="text") %>% 
    layout(autosize = F)
  • Separar os filmes entre os de bilheteria abaixo e acima de 50 milhões parece uma abordagem razoável.

  • “The Day After Tomorrow” aparenta formar um exército de um filme só. O que nos daria 3 grupos.

Avaliação

p <- filmes %>% 
    ggplot(aes(x = ano, 
               y = avaliacao,
                text = paste("Filme:",filme,
                            "\nAvaliação:",
                            avaliacao,
                            "\nAno:",ano))) + 
    geom_point(size = 4, color = paleta[1])  +
    scale_y_continuous(limits = c(0, 100)) +
    labs(y = "Avaliação RT", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
  • Entre 2005 e 2010 Jake participou de uma série de filmes em particular que não agradou os críticos
  • Não aparenta haver uma tendência particularmente clara em razão do ano de lançamento.
filmes %>% 
    ggplot(aes(x = avaliacao)) + 
    geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0, 
                   fill = paleta[3], color = "black") + 
    geom_rug(size = .5) +
    scale_x_continuous(breaks=seq(0,100,10)) +
    labs(y = "Frequência Relativa", x = "Avaliação RT")

  • É possível perceber uma quantidade considerável de filmes com notas acima de 80.

  • Nenhum valor fora do domínio de valores esperado, e.g. valores negativos.

p <- filmes %>% 
    ggplot(aes(x = "",
               y = avaliacao,
               text = paste(
                    "Filme:",filme,
                    "\nAvaliação:",avaliacao))) + 
    geom_jitter(width = .05, alpha = .3, size = 3) + 
    labs(x = "", y="Avaliação RT")
ggplotly(p, tooltip = "text") %>% 
    layout(autosize = F)
  • Intuitivamente três grupos surgem:
    • Os filmes com avaliação acima de 80
    • Os filmes com avaliação entre 55 e 70
    • Os filmes com avaliação abaixo de 55




Agrupamento hierárquico



Uma dimensão


Bilheteria

agrupamento_h = filmes %>% 
    mutate(nome = paste0(filme, " (bil=", bilheteria, ")")) %>% 
    as.data.frame() %>% 
    column_to_rownames("filme") %>% 
    select(bilheteria) %>%
    dist(method = "euclidian") %>% 
    hclust(method = "centroid")
ggdendrogram(agrupamento_h, rotate = T, size = 2, theme_dendro = F) +
    labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
    geom_hline(aes(yintercept = c(20,30), color=c("4 grupos","3 grupos"))) +
    scale_colour_manual(name="#Grupos",
    values=c("#56B4E9", "#FF9999"))

  • Em termos de Dendograma a divisão em quatro grupos assim como a divisão em 3 grupos parecem ser apropriadas, dado que o aumento de dissimilaridade de 4 para 3 grupos não aparentar ser substancial.
  • Corte feito para 4 grupos
atribuicoes = get_grupos(agrupamento_h, num_grupos = 1:6)
atribuicoes = atribuicoes %>% 
    left_join(filmes, by = c("label" = "filme"))
atribuicoes %>% 
    ggplot(aes(x = "Filmes", y = bilheteria, colour = grupo)) + 
    geom_jitter(width = .02, height = 0, size = 1.6, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") +
    labs(y = "Bilheteria (milhões)", x = "", title = "Agrupamento por Bilheteria")

  • A divisão em 4 grupos parece ser mais apropriada que a divisão em 3 grupos.
    • O cluster de filmes na base do gráfico aparenta exigir um grupo próprio (Na divisão em 4 grupos seria o grupo 1).
k_escolhido = 4
m <- list(l = 220)
p <-atribuicoes %>% 
    filter(k == k_escolhido) %>% 
    ggplot(aes(x = reorder(label, bilheteria),
               y = bilheteria,
               colour = grupo,
               text = paste(
                    "Filme:", reorder(label, bilheteria),
                    "\nAvaliação:", bilheteria,
                    "\nGrupo:", grupo))) + 
    geom_jitter(width = .02, height = 0, size = 3, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") + 
    labs(x = "", y = "Avaliação RT") + 
    coord_flip()
ggplotly(p,tooltip = "text") %>%
    layout(autosize = F, margin = m)
  • The Day After Tomorrow exigiu um grupo para si, como era esperado.


Avaliação

agrupamento_h = filmes %>% 
    mutate(nome = paste0(filme, " (av=", avaliacao, ")")) %>% 
    as.data.frame() %>% 
    column_to_rownames("filme") %>% 
    select(avaliacao) %>%
    dist(method = "euclidian") %>% 
    hclust(method = "ward.D")
ggdendrogram(agrupamento_h, rotate = T, size = 2, theme_dendro = F) +
    labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
    geom_hline(aes(yintercept = 30),color="red")

  • Em termos de Dendograma a divisão em três grupos parece ser a mais apropriada, dado que o aumento da dissimilaridade passa a ser substancial quando passamos de 3 para 2 grupos.
atribuicoes = get_grupos(agrupamento_h, num_grupos = 1:6)
atribuicoes = atribuicoes %>% 
    left_join(filmes, by = c("label" = "filme"))
atribuicoes %>% 
    ggplot(aes(x = "Filmes", y = avaliacao, colour = grupo)) + 
    geom_jitter(width = .02, height = 0, size = 1.6, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") +
    labs(y = "Avaliação RT", x = "", title = "Agrupamento por Avaliação")

  • Visualmente a divisão em três grupos parece de fato ser apropriada, o que está em acordo com o dendograma.
k_escolhido = 3
m <- list(l = 220)
p <-atribuicoes %>% 
    filter(k == k_escolhido) %>% 
    ggplot(aes(x = reorder(label, avaliacao),
               y = avaliacao,
               colour = grupo,
               text = paste(
                    "Filme:", reorder(label, avaliacao),
                    "\nAvaliação:", avaliacao,
                    "\nGrupo:", grupo))) + 
    geom_jitter(width = .02, height = 0, size = 3, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") + 
    labs(x = "", y = "Avaliação RT") + 
    coord_flip()
ggplotly(p,tooltip = "text") %>%
    layout(autosize = F, margin = m)
  • Discutivelmente, Prince of Persia: The Sands of Time poderia exigir um grupo para si próprio.


Duas dimensões

agrupamento_h_2d = filmes %>%
   mutate(bilheteria = log10(bilheteria)) %>%
   mutate_at(vars("avaliacao", "bilheteria"), funs(scale)) %>%
   column_to_rownames("filme") %>%
   select("avaliacao", "bilheteria") %>%
   dist(method = "euclidean") %>%
   hclust(method = "ward.D")
ggdendrogram(agrupamento_h_2d, rotate = TRUE, theme_dendro = F) +
    labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
    geom_hline(aes(yintercept = 4),color="red")

  • Passar de 4 para 3 grupos representa pouca variação em termos de dissimilaridade
  • Passar de 3 para 2 grupos apresentar um aumento relativo de dissimilaridade substancial, portanto 3 ou 4 grupos parece ser uma boa escolha.
filmes2 <- filmes %>%
    mutate(bilheteria = log10(bilheteria))
plota_hclusts_2d(agrupamento_h_2d,
                filmes2,
                c("avaliacao", "bilheteria"),
                linkage_method = "ward.D", 
                ks = 1:6,
                palette = "Dark2") + 
    scale_y_log10() +
    labs(y = "Bilheteria", x = "Avaliação", title = "Agrupamento com Duas Dimensões")

  • A escolha por 4 grupos parece ser apropriada, por refletir tanto questões de bilheteria como de avaliação. Em acordo com o que interpretamos no dendograma optaremos por 4 grupos.
atribuicoes = get_grupos(agrupamento_h_2d, num_grupos = 1:6)
atribuicoes = atribuicoes %>% 
    filter(k == 4) %>%
    mutate(filme = label) %>% 
    left_join(filmes, by = "filme")
p <- atribuicoes %>%
    ggplot(aes(x = avaliacao,
               y = bilheteria,
               colour = grupo,
               text = paste(
                    "Filme:", filme,
                    "\nBilheteria:", bilheteria,"m\n",
                    "Avaliação:", avaliacao))) + 
    geom_jitter(width = .02, height = 0, size = 3, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") +
    scale_y_log10() +
    labs(y = "Bilheteria", x = "Avaliação RT")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
  • Grupo 1 (Oddball): Filmes em geral bem recebidos pela crítica porém mal recebidos pelo público, o que se reflete no seu baixo arrecadamento.
    • Stronger: Filme biográfico sobre ‘Jeff Bauman’, vítima do atentado de Boston que perdeu ambas as pernas na explosão. O filme foi muito bem recebido pelos críticos que o elogiaram por ser bem executado, comovente e por focar numa história de superação ao invés de usar a tragédia para alimentar a paranóia em cima do terrorismo. O filme porém foi um fracasso em termos de bilheteria.


  • Grupo 2 (Sessão da Tarde): Filmes em geral não tão bem recebidos pela crítica e mais formulaicos. Em termos de bilheteria a maior parte deles foi baixa mas o filme se pagou, com duas exceções que arrecadaram melhor (‘Prince of Persia: The Sands of Time’ e ‘The Day After Tomorrow’). Para esse grupo existe uma curiosidade, para a maioria dos filmes desse grupo quanto maior o arrecadamento menor a avaliação.
    • Prince of Persia: The Sands of Time: Baseado no jogo de mesmo nome, este jogo uma referência em qualidade e inovação. O filme resultou em comentários decepcionados tanto de críticos e fãs que não falharam em contribuir pro arrecadamento do filme.


  • Grupo 3 (Demolition of a budget): Filmes em geral mal recebidos pela crítica e pelo público, o que se reflete no seu baixo arrecadamento e avaliações.
    • Demolition: Neste filme Jake atua no papel de um homem que volta ao trabalho depois de perder a esposa e encontra contato humano em uma atendente de telemarketing ao reclamar de uma vending machine. O filme foi um fracasso em termos de arrecadamento assim como em termos de crítica. O filme teve seu script apontado como grande problema, esse foi descrito como ‘tentando afetar profundidade’ e anti-carismático.


  • Grupo 4 (Brokeback Mountain): Filmes aclamados pela crítica e de faturamento decente ou de sucesso, os filmes dese grupo são de tom mais sério tratando de assuntos significativos e geradores de controvérsia (assassinatos em série verídicos, não heterossexualidade, terrorismo.. ).
    • Brokeback Mountain: Provavelmente a melhor atuação de Jake Gyllenhaal até o momento, esse filme rendeu a Jake uma indicação ao Oscar e levantou muita controvérsia por conter uma cena de sexo entre pessoas do mesmo sexo. A Academia (responsável por escolher os vencedores do Oscar) foi acusada de homofobia por não escolher esse filme como o ganhador de Melhor Fotografia, ainda assim Brokeback Mountain ganhou mais ganhou 141 prêmios e 128 nominações de acordo com o IMDB. O filme foi considerado um sucesso tanto em faturamento como em avaliação.
LS0tCnRpdGxlOiAiVGlwb3MgZGUgZmlsbWUgZGUgSmFrZSBHeWxsZW5oYWFsIgphdXRob3I6ICJKb3PDqSBCZW5hcmRpIGRlIFNvdXphIE51bmVzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwotLS0KCiMgSW50cm9kdcOnw6NvCgo+IEFuw6FsaXNlIGV4cGxvcmF0w7NyaWEgZGUgZGFkb3MgZG8gW1JvdHRlblRvbWF0b2VzXShodHRwczovL3d3dy5yb3R0ZW50b21hdG9lcy5jb20vKSBzb2JyZSBvIGF0b3IgSmFrZSBHeWxsZW5oYWFsLiBPIGPDs2RpZ28gZW1wcmVnYWRvIG5hIGV4dHJhw6fDo28gZG9zIGRhZG9zIGFxdWkgYW5hbGl6YWRvcyBlIGEgZGVzY3Jpw6fDo28gZGUgY29tbyBvIHVzYXIgZW5jb250cmEtc2Ugbm8gIFtyZXBvc2l0w7NyaW8gb3JpZ2VtXShodHRwczovL2dpdGh1Yi5jb20vQmVuYXJkaS9hZ3J1cGFtZW50by1maWxtZXMvKSBkZXN0ZSByZWxhdMOzcmlvLgoKKiBFbnRyYWRhcyBxdWUgbsOjbyBjb250w6ptIGRhZG9zIHNvYnJlIGJpbGhldGVyaWEgZm9yYW0gaWdub3JhZG9zLgoKPGJyPgoKKioqCgo8YnI+CgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShoZXJlKQpsaWJyYXJ5KGNsdXN0ZXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdnZGVuZHJvKQoKc291cmNlKGhlcmU6OmhlcmUoImNvZGUvbGliLlIiKSkKc291cmNlKGhlcmU6OmhlcmUoImNvZGUvcGxvdGFfc29sdWNvZXNfaGNsdXN0LlIiKSkKCnRoZW1lX3NldCh0aGVtZV9yZXBvcnQoKSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA2LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSkKcGFsZXRhID0gYygiIzQwNEU0RCIsCiAgICAgICAgICAgIiM5MkRDRTUiLAogICAgICAgICAgICIjOTM4QkExIiwKICAgICAgICAgICAiIzJEMzE0MiIsCiAgICAgICAgICAgIiNGNDc0M0IiKQpgYGAKCiMgRGF0YSBPdmVydmlldwoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KaW1wb3J0X2RhdGEoImpha2VfZ3lsbGVuaGFhbCIpIApmaWxtZXMgPC0gcmVhZF9pbXBvcnRlZF9kYXRhKCkKZmlsbWVzICU+JSAKICAgIGdsaW1wc2UoKQpgYGAKCiMjIEJpbGhldGVyaWEKCiogRGFkb3MgZGUgYmlsaGV0ZXJpYSBzZSByZWZlcmVtIGFvIGFycmVjYWRhbWVudG8gZGVudHJvIGRvcyBFc3RhZG9zIFVuaWRvcy4KCmBgYHtyfQpwIDwtIGZpbG1lcyAlPiUKICAgIGdncGxvdChhZXMoeCA9IGFubywgCiAgICAgICAgICAgICAgIHkgPSBiaWxoZXRlcmlhLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIkZpbG1lOiIsZmlsbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5CaWxoZXRlcmlhOiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWxoZXRlcmlhLCJtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbkFubzoiLGFubykpKSArIAogICAgZ2VvbV9wb2ludChzaXplID0gNCwgY29sb3IgPSBwYWxldGFbMV0pICsKICAgIGxhYnMoeSA9ICJCaWxoZXRlcmlhIiwgeCA9ICJBbm8gZGUgbGFuw6dhbWVudG8iKQoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiogRW50cmUgb3MgZmlsbWVzIGVtIHF1ZSBKYWtlIGF0dW91IHVtIGZvZ2UgYW9zIG91dHJvcyBlbSB0ZXJtb3MgZGUgZmF0dXJhbWVudG8sIG8gZmlsbWUgICoqIlRoZSBEYXkgQWZ0ZXIgVG9tb3Jyb3ciKiogbGFuw6dhZG8gZW0gMjAwNC4KCiogw4kgcG9zc8OtdmVsIHBlcmNlYmVyIHVtYSB0ZW5kw6puY2lhIGRlIHF1ZWRhIG5vIGZhdHVyYW1lbnRvIGRvcyBmaWxtZXMgZW0gcXVlIEpha2UgYXR1b3UgYXDDs3MgMjAxMy4KCmBgYHtyfQpmaWxtZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gYmlsaGV0ZXJpYSkpICsgCiAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeT0oLi5jb3VudC4uKS9zdW0oLi5jb3VudC4uKSksYmlud2lkdGggPSAxMCwgYm91bmRhcnkgPSAwLCAKICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiZ3JleSIsIGNvbG9yID0gImJsYWNrIikgKyAKICAgIGdlb21fcnVnKHNpemUgPSAuNSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwyMDAsMjApKSArCiAgICBsYWJzKHkgPSAiRnJlcXXDqm5jaWEgUmVsYXRpdmEiLCB4ID0gIkJpbGhldGVyaWEiKQoKYGBgCgoqIFZlbW9zIGNsYXJhbWVudGUgYSBkaXNwYXJpZGFkZSBlbnRyZSAqKiJUaGUgRGF5IEFmdGVyIFRvbW9ycm93IioqICBlIG9zIG91dHJvcyBmaWxtZXMuCgoqIE5lbmh1bSB2YWxvciBmb3JhIGRvIGRvbcOtbmlvIGRlIHZhbG9yZXMgZXNwZXJhZG8sIGUuZy4gdmFsb3JlcyBuZWdhdGl2b3MuCgpgYGB7cn0KcCA8LSBmaWxtZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gIiIsCiAgICAgICAgICAgICAgIHkgPSBiaWxoZXRlcmlhLAogICAgICAgICAgICAgICBsYWJlbCA9IGZpbG1lLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIkZpbG1lOiIsZmlsbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5CaWxoZXRlcmlhOiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWxoZXRlcmlhLCJtIikpKSArIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMDUsIGFscGhhID0gLjMsIHNpemUgPSAzKSArIAogICAgbGFicyh4ID0gIiIsIHk9IkJpbGhldGVyaWEiKQoKZ2dwbG90bHkocCwgdG9vbHRpcD0idGV4dCIpICU+JSAKICAgIGxheW91dChhdXRvc2l6ZSA9IEYpCmBgYAoKKiBTZXBhcmFyIG9zIGZpbG1lcyBlbnRyZSBvcyBkZSBiaWxoZXRlcmlhIGFiYWl4byBlIGFjaW1hIGRlIDUwIG1pbGjDtWVzIHBhcmVjZSB1bWEgYWJvcmRhZ2VtIHJhem/DoXZlbC4KCiogKioiVGhlIERheSBBZnRlciBUb21vcnJvdyIqKiBhcGFyZW50YSBmb3JtYXIgdW0gZXjDqXJjaXRvIGRlIHVtIGZpbG1lIHPDsy4gTyBxdWUgbm9zIGRhcmlhIDMgZ3J1cG9zLiAKCiMjIEF2YWxpYcOnw6NvCgpgYGB7cn0KcCA8LSBmaWxtZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gYW5vLCAKICAgICAgICAgICAgICAgeSA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiRmlsbWU6IixmaWxtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbkF2YWxpYcOnw6NvOiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5Bbm86Iixhbm8pKSkgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGNvbG9yID0gcGFsZXRhWzFdKSAgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTAwKSkgKwogICAgbGFicyh5ID0gIkF2YWxpYcOnw6NvIFJUIiwgeCA9ICJBbm8gZGUgbGFuw6dhbWVudG8iKQoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiogRW50cmUgMjAwNSBlIDIwMTAgSmFrZSBwYXJ0aWNpcG91IGRlIHVtYSBzw6lyaWUgZGUgZmlsbWVzIGVtIHBhcnRpY3VsYXIgcXVlIG7Do28gYWdyYWRvdSBvcyBjcsOtdGljb3MgCiogTsOjbyBhcGFyZW50YSBoYXZlciB1bWEgdGVuZMOqbmNpYSBwYXJ0aWN1bGFybWVudGUgY2xhcmEgZW0gcmF6w6NvIGRvIGFubyBkZSBsYW7Dp2FtZW50by4gCgpgYGB7cn0KZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGF2YWxpYWNhbykpICsgCiAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeT0oLi5jb3VudC4uKS9zdW0oLi5jb3VudC4uKSksYmlud2lkdGggPSAxMCwgYm91bmRhcnkgPSAwLCAKICAgICAgICAgICAgICAgICAgIGZpbGwgPSBwYWxldGFbM10sIGNvbG9yID0gImJsYWNrIikgKyAKICAgIGdlb21fcnVnKHNpemUgPSAuNSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxMDAsMTApKSArCiAgICBsYWJzKHkgPSAiRnJlcXXDqm5jaWEgUmVsYXRpdmEiLCB4ID0gIkF2YWxpYcOnw6NvIFJUIikKCmBgYAoKKiDDiSBwb3Nzw612ZWwgcGVyY2ViZXIgdW1hIHF1YW50aWRhZGUgY29uc2lkZXLDoXZlbCBkZSBmaWxtZXMgY29tIG5vdGFzIGFjaW1hIGRlIDgwLgoKKiBOZW5odW0gdmFsb3IgZm9yYSBkbyBkb23DrW5pbyBkZSB2YWxvcmVzIGVzcGVyYWRvLCBlLmcuIHZhbG9yZXMgbmVnYXRpdm9zLgoKCmBgYHtyfQpwIDwtIGZpbG1lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSAiIiwKICAgICAgICAgICAgICAgeSA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKAogICAgICAgICAgICAgICAgICAgICJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICJcbkF2YWxpYcOnw6NvOiIsYXZhbGlhY2FvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wNSwgYWxwaGEgPSAuMywgc2l6ZSA9IDMpICsgCiAgICBsYWJzKHggPSAiIiwgeT0iQXZhbGlhw6fDo28gUlQiKQoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogICAgbGF5b3V0KGF1dG9zaXplID0gRikKCmBgYAoKKiBJbnR1aXRpdmFtZW50ZSB0csOqcyBncnVwb3Mgc3VyZ2VtOgogICAgKiBPcyBmaWxtZXMgY29tIGF2YWxpYcOnw6NvIGFjaW1hIGRlIDgwCiAgICAqIE9zIGZpbG1lcyBjb20gYXZhbGlhw6fDo28gZW50cmUgNTUgZSA3MCAKICAgICogT3MgZmlsbWVzIGNvbSBhdmFsaWHDp8OjbyBhYmFpeG8gZGUgNTUKCjxicj4KCioqKgoKPGJyPgoKIyBBZ3J1cGFtZW50byBoaWVyw6FycXVpY28KCjxicj4KPGJyPgoKIyMgVW1hIGRpbWVuc8OjbwoKPGJyPgoKIyMjIEJpbGhldGVyaWEgCgpgYGB7cn0KYWdydXBhbWVudG9faCA9IGZpbG1lcyAlPiUgCiAgICBtdXRhdGUobm9tZSA9IHBhc3RlMChmaWxtZSwgIiAoYmlsPSIsIGJpbGhldGVyaWEsICIpIikpICU+JSAKICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgICBjb2x1bW5fdG9fcm93bmFtZXMoImZpbG1lIikgJT4lIAogICAgc2VsZWN0KGJpbGhldGVyaWEpICU+JQogICAgZGlzdChtZXRob2QgPSAiZXVjbGlkaWFuIikgJT4lIAogICAgaGNsdXN0KG1ldGhvZCA9ICJjZW50cm9pZCIpCgpnZ2RlbmRyb2dyYW0oYWdydXBhbWVudG9faCwgcm90YXRlID0gVCwgc2l6ZSA9IDIsIHRoZW1lX2RlbmRybyA9IEYpICsKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikgKwogICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IGMoMjAsMzApLCBjb2xvcj1jKCI0IGdydXBvcyIsIjMgZ3J1cG9zIikpKSArCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKG5hbWU9IiNHcnVwb3MiLAogICAgdmFsdWVzPWMoIiM1NkI0RTkiLCAiI0ZGOTk5OSIpKQpgYGAKCiogRW0gdGVybW9zIGRlIERlbmRvZ3JhbWEgYSBkaXZpc8OjbyBlbSBxdWF0cm8gZ3J1cG9zIGFzc2ltIGNvbW8gYSBkaXZpc8OjbyBlbSAzIGdydXBvcyBwYXJlY2VtIHNlciBhcHJvcHJpYWRhcywgZGFkbyBxdWUgbyBhdW1lbnRvIGRlIGRpc3NpbWlsYXJpZGFkZSBkZSA0IHBhcmEgMyBncnVwb3MgbsOjbyBhcGFyZW50YXIgc2VyIHN1YnN0YW5jaWFsLgoqICBDb3J0ZSBmZWl0byBwYXJhIDQgZ3J1cG9zCgpgYGB7cn0KYXRyaWJ1aWNvZXMgPSBnZXRfZ3J1cG9zKGFncnVwYW1lbnRvX2gsIG51bV9ncnVwb3MgPSAxOjYpCgphdHJpYnVpY29lcyA9IGF0cmlidWljb2VzICU+JSAKICAgIGxlZnRfam9pbihmaWxtZXMsIGJ5ID0gYygibGFiZWwiID0gImZpbG1lIikpCgphdHJpYnVpY29lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSAiRmlsbWVzIiwgeSA9IGJpbGhldGVyaWEsIGNvbG91ciA9IGdydXBvKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjAyLCBoZWlnaHQgPSAwLCBzaXplID0gMS42LCBhbHBoYSA9IC42KSArIAogICAgZmFjZXRfd3JhcCh+IHBhc3RlKGssICIgZ3J1cG9zIikpICsgCiAgICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICAgIGxhYnMoeSA9ICJCaWxoZXRlcmlhIChtaWxow7VlcykiLCB4ID0gIiIsIHRpdGxlID0gIkFncnVwYW1lbnRvIHBvciBCaWxoZXRlcmlhIikKCmBgYAoKKiBBIGRpdmlzw6NvIGVtIDQgZ3J1cG9zIHBhcmVjZSBzZXIgbWFpcyBhcHJvcHJpYWRhIHF1ZSBhIGRpdmlzw6NvIGVtIDMgZ3J1cG9zLgogICAgKiBPIGNsdXN0ZXIgZGUgZmlsbWVzIG5hIGJhc2UgZG8gZ3LDoWZpY28gYXBhcmVudGEgZXhpZ2lyIHVtIGdydXBvIHByw7NwcmlvIChOYSBkaXZpc8OjbyBlbSA0IGdydXBvcyBzZXJpYSBvIGdydXBvIDEpLiAKCmBgYHtyfQprX2VzY29saGlkbyA9IDQKCm0gPC0gbGlzdChsID0gMjIwKQoKcCA8LWF0cmlidWljb2VzICU+JSAKICAgIGZpbHRlcihrID09IGtfZXNjb2xoaWRvKSAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyKGxhYmVsLCBiaWxoZXRlcmlhKSwKICAgICAgICAgICAgICAgeSA9IGJpbGhldGVyaWEsCiAgICAgICAgICAgICAgIGNvbG91ciA9IGdydXBvLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoCiAgICAgICAgICAgICAgICAgICAgIkZpbG1lOiIsIHJlb3JkZXIobGFiZWwsIGJpbGhldGVyaWEpLAogICAgICAgICAgICAgICAgICAgICJcbkF2YWxpYcOnw6NvOiIsIGJpbGhldGVyaWEsCiAgICAgICAgICAgICAgICAgICAgIlxuR3J1cG86IiwgZ3J1cG8pKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjAyLCBoZWlnaHQgPSAwLCBzaXplID0gMywgYWxwaGEgPSAuNikgKyAKICAgIGZhY2V0X3dyYXAofiBwYXN0ZShrLCAiIGdydXBvcyIpKSArIAogICAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArIAogICAgbGFicyh4ID0gIiIsIHkgPSAiQXZhbGlhw6fDo28gUlQiKSArIAogICAgY29vcmRfZmxpcCgpCgpnZ3Bsb3RseShwLHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRiwgbWFyZ2luID0gbSkKCmBgYAoKKiAqKlRoZSBEYXkgQWZ0ZXIgVG9tb3Jyb3cqKiBleGlnaXUgdW0gZ3J1cG8gcGFyYSBzaSwgY29tbyBlcmEgZXNwZXJhZG8uCgo8YnI+CgojIyMgQXZhbGlhw6fDo28gCgpgYGB7cn0KYWdydXBhbWVudG9faCA9IGZpbG1lcyAlPiUgCiAgICBtdXRhdGUobm9tZSA9IHBhc3RlMChmaWxtZSwgIiAoYXY9IiwgYXZhbGlhY2FvLCAiKSIpKSAlPiUgCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgY29sdW1uX3RvX3Jvd25hbWVzKCJmaWxtZSIpICU+JSAKICAgIHNlbGVjdChhdmFsaWFjYW8pICU+JQogICAgZGlzdChtZXRob2QgPSAiZXVjbGlkaWFuIikgJT4lIAogICAgaGNsdXN0KG1ldGhvZCA9ICJ3YXJkLkQiKQoKZ2dkZW5kcm9ncmFtKGFncnVwYW1lbnRvX2gsIHJvdGF0ZSA9IFQsIHNpemUgPSAyLCB0aGVtZV9kZW5kcm8gPSBGKSArCiAgICBsYWJzKHkgPSAiRGlzc2ltaWxhcmlkYWRlIiwgeCA9ICIiLCB0aXRsZSA9ICJEZW5kcm9ncmFtYSIpICsKICAgIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAzMCksY29sb3I9InJlZCIpCmBgYAoKKiBFbSB0ZXJtb3MgZGUgRGVuZG9ncmFtYSBhICoqZGl2aXPDo28gZW0gdHLDqnMgZ3J1cG9zIHBhcmVjZSBzZXIgYSBtYWlzIGFwcm9wcmlhZGEqKiwgZGFkbyBxdWUgbyBhdW1lbnRvIGRhIGRpc3NpbWlsYXJpZGFkZSBwYXNzYSBhIHNlciBzdWJzdGFuY2lhbCBxdWFuZG8gcGFzc2Ftb3MgZGUgMyBwYXJhIDIgZ3J1cG9zLgoKYGBge3J9CmF0cmlidWljb2VzID0gZ2V0X2dydXBvcyhhZ3J1cGFtZW50b19oLCBudW1fZ3J1cG9zID0gMTo2KQoKYXRyaWJ1aWNvZXMgPSBhdHJpYnVpY29lcyAlPiUgCiAgICBsZWZ0X2pvaW4oZmlsbWVzLCBieSA9IGMoImxhYmVsIiA9ICJmaWxtZSIpKQoKYXRyaWJ1aWNvZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gIkZpbG1lcyIsIHkgPSBhdmFsaWFjYW8sIGNvbG91ciA9IGdydXBvKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjAyLCBoZWlnaHQgPSAwLCBzaXplID0gMS42LCBhbHBoYSA9IC42KSArIAogICAgZmFjZXRfd3JhcCh+IHBhc3RlKGssICIgZ3J1cG9zIikpICsgCiAgICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICAgIGxhYnMoeSA9ICJBdmFsaWHDp8OjbyBSVCIsIHggPSAiIiwgdGl0bGUgPSAiQWdydXBhbWVudG8gcG9yIEF2YWxpYcOnw6NvIikKCmBgYAoKKiBWaXN1YWxtZW50ZSBhIGRpdmlzw6NvIGVtIHRyw6pzIGdydXBvcyBwYXJlY2UgZGUgZmF0byBzZXIgYXByb3ByaWFkYSwgbyBxdWUgZXN0w6EgZW0gYWNvcmRvIGNvbSBvIGRlbmRvZ3JhbWEuCgpgYGB7cn0Ka19lc2NvbGhpZG8gPSAzCgptIDwtIGxpc3QobCA9IDIyMCkKCnAgPC1hdHJpYnVpY29lcyAlPiUgCiAgICBmaWx0ZXIoayA9PSBrX2VzY29saGlkbykgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihsYWJlbCwgYXZhbGlhY2FvKSwKICAgICAgICAgICAgICAgeSA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgY29sb3VyID0gZ3J1cG8sCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgKICAgICAgICAgICAgICAgICAgICAiRmlsbWU6IiwgcmVvcmRlcihsYWJlbCwgYXZhbGlhY2FvKSwKICAgICAgICAgICAgICAgICAgICAiXG5BdmFsaWHDp8OjbzoiLCBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgICAgICAgIlxuR3J1cG86IiwgZ3J1cG8pKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjAyLCBoZWlnaHQgPSAwLCBzaXplID0gMywgYWxwaGEgPSAuNikgKyAKICAgIGZhY2V0X3dyYXAofiBwYXN0ZShrLCAiIGdydXBvcyIpKSArIAogICAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArIAogICAgbGFicyh4ID0gIiIsIHkgPSAiQXZhbGlhw6fDo28gUlQiKSArIAogICAgY29vcmRfZmxpcCgpCgpnZ3Bsb3RseShwLHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRiwgbWFyZ2luID0gbSkKCmBgYAoKKiBEaXNjdXRpdmVsbWVudGUsICoqUHJpbmNlIG9mIFBlcnNpYTogVGhlIFNhbmRzIG9mIFRpbWUqKiBwb2RlcmlhIGV4aWdpciB1bSBncnVwbyBwYXJhIHNpIHByw7NwcmlvLgoKPGJyPgoKIyMgRHVhcyBkaW1lbnPDtWVzCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KYWdydXBhbWVudG9faF8yZCA9IGZpbG1lcyAlPiUKICAgbXV0YXRlKGJpbGhldGVyaWEgPSBsb2cxMChiaWxoZXRlcmlhKSkgJT4lCiAgIG11dGF0ZV9hdCh2YXJzKCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpLCBmdW5zKHNjYWxlKSkgJT4lCiAgIGNvbHVtbl90b19yb3duYW1lcygiZmlsbWUiKSAlPiUKICAgc2VsZWN0KCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpICU+JQogICBkaXN0KG1ldGhvZCA9ICJldWNsaWRlYW4iKSAlPiUKICAgaGNsdXN0KG1ldGhvZCA9ICJ3YXJkLkQiKQoKZ2dkZW5kcm9ncmFtKGFncnVwYW1lbnRvX2hfMmQsIHJvdGF0ZSA9IFRSVUUsIHRoZW1lX2RlbmRybyA9IEYpICsKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikgKwogICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDQpLGNvbG9yPSJyZWQiKQoKYGBgCgoqIFBhc3NhciBkZSA0IHBhcmEgMyBncnVwb3MgcmVwcmVzZW50YSBwb3VjYSB2YXJpYcOnw6NvIGVtIHRlcm1vcyBkZSBkaXNzaW1pbGFyaWRhZGUKKiBQYXNzYXIgZGUgMyBwYXJhIDIgZ3J1cG9zIGFwcmVzZW50YXIgdW0gYXVtZW50byByZWxhdGl2byBkZSBkaXNzaW1pbGFyaWRhZGUgc3Vic3RhbmNpYWwsIHBvcnRhbnRvIDMgb3UgNCBncnVwb3MgcGFyZWNlIHNlciB1bWEgYm9hIGVzY29saGEuCgpgYGB7cn0KZmlsbWVzMiA8LSBmaWxtZXMgJT4lCiAgICBtdXRhdGUoYmlsaGV0ZXJpYSA9IGxvZzEwKGJpbGhldGVyaWEpKQoKcGxvdGFfaGNsdXN0c18yZChhZ3J1cGFtZW50b19oXzJkLAogICAgICAgICAgICAgICAgZmlsbWVzMiwKICAgICAgICAgICAgICAgIGMoImF2YWxpYWNhbyIsICJiaWxoZXRlcmlhIiksCiAgICAgICAgICAgICAgICBsaW5rYWdlX21ldGhvZCA9ICJ3YXJkLkQiLCAKICAgICAgICAgICAgICAgIGtzID0gMTo2LAogICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJEYXJrMiIpICsgCiAgICBzY2FsZV95X2xvZzEwKCkgKwogICAgbGFicyh5ID0gIkJpbGhldGVyaWEiLCB4ID0gIkF2YWxpYcOnw6NvIiwgdGl0bGUgPSAiQWdydXBhbWVudG8gY29tIER1YXMgRGltZW5zw7VlcyIpCmBgYAoKKiBBIGVzY29saGEgcG9yIDQgZ3J1cG9zIHBhcmVjZSBzZXIgYXByb3ByaWFkYSwgcG9yIHJlZmxldGlyIHRhbnRvIHF1ZXN0w7VlcyBkZSBiaWxoZXRlcmlhIGNvbW8gZGUgYXZhbGlhw6fDo28uIEVtIGFjb3JkbyBjb20gbyBxdWUgaW50ZXJwcmV0YW1vcyBubyBkZW5kb2dyYW1hICoqb3B0YXJlbW9zIHBvciA0IGdydXBvcy4qKiAKCmBgYHtyfQphdHJpYnVpY29lcyA9IGdldF9ncnVwb3MoYWdydXBhbWVudG9faF8yZCwgbnVtX2dydXBvcyA9IDE6NikKCmF0cmlidWljb2VzID0gYXRyaWJ1aWNvZXMgJT4lIAogICAgZmlsdGVyKGsgPT0gNCkgJT4lCiAgICBtdXRhdGUoZmlsbWUgPSBsYWJlbCkgJT4lIAogICAgbGVmdF9qb2luKGZpbG1lcywgYnkgPSAiZmlsbWUiKQoKcCA8LSBhdHJpYnVpY29lcyAlPiUKICAgIGdncGxvdChhZXMoeCA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgeSA9IGJpbGhldGVyaWEsCiAgICAgICAgICAgICAgIGNvbG91ciA9IGdydXBvLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoCiAgICAgICAgICAgICAgICAgICAgIkZpbG1lOiIsIGZpbG1lLAogICAgICAgICAgICAgICAgICAgICJcbkJpbGhldGVyaWE6IiwgYmlsaGV0ZXJpYSwibVxuIiwKICAgICAgICAgICAgICAgICAgICAiQXZhbGlhw6fDo286IiwgYXZhbGlhY2FvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wMiwgaGVpZ2h0ID0gMCwgc2l6ZSA9IDMsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogICAgc2NhbGVfeV9sb2cxMCgpICsKICAgIGxhYnMoeSA9ICJCaWxoZXRlcmlhIiwgeCA9ICJBdmFsaWHDp8OjbyBSVCIpCgoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiogKipHcnVwbyAxIChPZGRiYWxsKSoqOiBGaWxtZXMgZW0gZ2VyYWwgX2JlbSByZWNlYmlkb3MgcGVsYSBjcsOtdGljYSBwb3LDqW0gbWFsIHJlY2ViaWRvcyBwZWxvIHDDumJsaWNvXywgbyBxdWUgc2UgcmVmbGV0ZSBubyBzZXUgYmFpeG8gYXJyZWNhZGFtZW50by4KICAgICogKipTdHJvbmdlcioqOiBGaWxtZSBiaW9ncsOhZmljbyBzb2JyZSAnSmVmZiBCYXVtYW4nLCB2w610aW1hIGRvIGF0ZW50YWRvIGRlIEJvc3RvbiBxdWUgcGVyZGV1IGFtYmFzIGFzIHBlcm5hcyBuYSBleHBsb3PDo28uIE8gZmlsbWUgZm9pIG11aXRvIGJlbSByZWNlYmlkbyBwZWxvcyBjcsOtdGljb3MgcXVlIG8gZWxvZ2lhcmFtIHBvciBzZXIgYmVtIGV4ZWN1dGFkbywgY29tb3ZlbnRlIGUgcG9yIGZvY2FyIG51bWEgaGlzdMOzcmlhIGRlIHN1cGVyYcOnw6NvIGFvIGludsOpcyBkZSB1c2FyIGEgdHJhZ8OpZGlhIHBhcmEgYWxpbWVudGFyIGEgcGFyYW7Ds2lhIGVtIGNpbWEgZG8gdGVycm9yaXNtby4gTyBmaWxtZSBwb3LDqW0gZm9pIHVtIGZyYWNhc3NvIGVtIHRlcm1vcyBkZSBiaWxoZXRlcmlhLgoKPGJyLz4KCiogKipHcnVwbyAyIChTZXNzw6NvIGRhIFRhcmRlKSoqOiBGaWxtZXMgZW0gZ2VyYWwgX27Do28gdMOjbyBiZW0gcmVjZWJpZG9zIHBlbGEgY3LDrXRpY2EgZSBtYWlzIGZvcm11bGFpY29zXy4gRW0gdGVybW9zIGRlIGJpbGhldGVyaWEgYSBtYWlvciBwYXJ0ZSBkZWxlcyBmb2kgYmFpeGEgbWFzIG8gZmlsbWUgc2UgcGFnb3UsIGNvbSBkdWFzIGV4Y2XDp8O1ZXMgcXVlIGFycmVjYWRhcmFtIG1lbGhvciAoJ1ByaW5jZSBvZiBQZXJzaWE6IFRoZSBTYW5kcyBvZiBUaW1lJyBlICdUaGUgRGF5IEFmdGVyIFRvbW9ycm93JykuIFBhcmEgZXNzZSBncnVwbyBleGlzdGUgdW1hIGN1cmlvc2lkYWRlLCBwYXJhIGEgX21haW9yaWFfIGRvcyBmaWxtZXMgZGVzc2UgZ3J1cG8gcXVhbnRvIG1haW9yIG8gYXJyZWNhZGFtZW50byBtZW5vciBhIGF2YWxpYcOnw6NvLgogICAgKiAqKlByaW5jZSBvZiBQZXJzaWE6IFRoZSBTYW5kcyBvZiBUaW1lKio6IEJhc2VhZG8gbm8gam9nbyBkZSBtZXNtbyBub21lLCBlc3RlIGpvZ28gdW1hIHJlZmVyw6puY2lhIGVtIHF1YWxpZGFkZSBlIGlub3Zhw6fDo28uIE8gZmlsbWUgcmVzdWx0b3UgZW0gY29tZW50w6FyaW9zIGRlY2VwY2lvbmFkb3MgdGFudG8gZGUgY3LDrXRpY29zIGUgZsOjcyBxdWUgbsOjbyBmYWxoYXJhbSBlbSBjb250cmlidWlyIHBybyBhcnJlY2FkYW1lbnRvIGRvIGZpbG1lLgoKPGJyLz4KCiogKipHcnVwbyAzIChEZW1vbGl0aW9uIH5+b2YgYSBidWRnZXR+fikqKjogRmlsbWVzIGVtIGdlcmFsIF9tYWwgcmVjZWJpZG9zIHBlbGEgY3LDrXRpY2EgZSBwZWxvIHDDumJsaWNvXywgbyBxdWUgc2UgcmVmbGV0ZSBubyBzZXUgYmFpeG8gYXJyZWNhZGFtZW50byBlIGF2YWxpYcOnw7Vlcy4gCiAgICAqICoqRGVtb2xpdGlvbioqOiBOZXN0ZSBmaWxtZSBKYWtlIGF0dWEgbm8gcGFwZWwgZGUgdW0gaG9tZW0gcXVlIHZvbHRhIGFvIHRyYWJhbGhvIGRlcG9pcyBkZSBwZXJkZXIgYSBlc3Bvc2EgZSBlbmNvbnRyYSBjb250YXRvIGh1bWFubyBlbSB1bWEgYXRlbmRlbnRlIGRlIHRlbGVtYXJrZXRpbmcgYW8gcmVjbGFtYXIgZGUgdW1hIHZlbmRpbmcgbWFjaGluZS4gTyBmaWxtZSBmb2kgdW0gZnJhY2Fzc28gZW0gdGVybW9zIGRlIGFycmVjYWRhbWVudG8gYXNzaW0gY29tbyBlbSB0ZXJtb3MgZGUgY3LDrXRpY2EuIE8gZmlsbWUgdGV2ZSBzZXUgc2NyaXB0IGFwb250YWRvIGNvbW8gZ3JhbmRlIHByb2JsZW1hLCBlc3NlIGZvaSBkZXNjcml0byBjb21vICd0ZW50YW5kbyBhZmV0YXIgcHJvZnVuZGlkYWRlJyBlIGFudGktY2FyaXNtw6F0aWNvLgogICAgCjxici8+CgoqICoqR3J1cG8gNCAoQnJva2ViYWNrIE1vdW50YWluKSoqOiBGaWxtZXMgX2FjbGFtYWRvcyBwZWxhIGNyw610aWNhXyBlIGRlIGZhdHVyYW1lbnRvIGRlY2VudGUgb3UgZGUgIHN1Y2Vzc28sIG9zIGZpbG1lcyBkZXNlIGdydXBvIHPDo28gZGUgdG9tIG1haXMgc8OpcmlvIHRyYXRhbmRvIGRlIGFzc3VudG9zIHNpZ25pZmljYXRpdm9zIGUgZ2VyYWRvcmVzIGRlIGNvbnRyb3bDqXJzaWEgKGFzc2Fzc2luYXRvcyBlbSBzw6lyaWUgdmVyw61kaWNvcywgbsOjbyBoZXRlcm9zc2V4dWFsaWRhZGUsIHRlcnJvcmlzbW8uLiApLiAKICAgICogKipCcm9rZWJhY2sgTW91bnRhaW4qKjogUHJvdmF2ZWxtZW50ZSBhIG1lbGhvciBhdHVhw6fDo28gZGUgSmFrZSBHeWxsZW5oYWFsIGF0w6kgbyBtb21lbnRvLCBlc3NlIGZpbG1lIHJlbmRldSBhIEpha2UgdW1hIGluZGljYcOnw6NvIGFvIE9zY2FyIGUgbGV2YW50b3UgbXVpdGEgY29udHJvdsOpcnNpYSBwb3IgY29udGVyIHVtYSBjZW5hIGRlIHNleG8gZW50cmUgcGVzc29hcyBkbyBtZXNtbyBzZXhvLiBBIEFjYWRlbWlhIChyZXNwb25zw6F2ZWwgcG9yIGVzY29saGVyIG9zIHZlbmNlZG9yZXMgZG8gT3NjYXIpIGZvaSBhY3VzYWRhIGRlIGhvbW9mb2JpYSBwb3IgbsOjbyBlc2NvbGhlciBlc3NlIGZpbG1lIGNvbW8gbyBnYW5oYWRvciBkZSBNZWxob3IgRm90b2dyYWZpYSwgYWluZGEgYXNzaW0gQnJva2ViYWNrIE1vdW50YWluIGdhbmhvdSBtYWlzIGdhbmhvdSAxNDEgcHLDqm1pb3MgZSAxMjggbm9taW5hw6fDtWVzIGRlIGFjb3JkbyBjb20gbyBJTURCLiBPIGZpbG1lIGZvaSBjb25zaWRlcmFkbyB1bSBzdWNlc3NvIHRhbnRvIGVtIGZhdHVyYW1lbnRvIGNvbW8gZW0gYXZhbGlhw6fDo28uCiAgICAK